using BitMango.Diagnostics;
using System.Collections.Generic;
using UnityEngine;

public class BoxRootWidgetHandler : MonoBehaviour, IWidget, IHandlerBase
{
    [HideInInspector]
    public byte[] subBlock;

    [HideInInspector]
    public List<BoxWidgetHandler> boxWidgets = new List<BoxWidgetHandler>();

    public List<Point> points = new List<Point>();

    [HideInInspector]
    public bool isPermitClick = true;

    [HideInInspector]
    public int rootIndex = -1;

    [HideInInspector]
    public bool usedHint;

    [HideInInspector]
    public BoxWidgetHandler rotateRoot;

    [HideInInspector]
    public bool isSet;

    private BlockType blockType;

    private bool isReverse;

    private byte[] editMinPoint = new byte[2];

    private int colorIndex;

    private GameObject parent;

    public void SetData(GameObject _parent, byte[] _subBlock, int _index, int _colorIndex, bool _isReverse, byte[] _editMinPoint, BlockType _blockType)
    {
        Debugger.Assert(_parent != null, "BoxRootWidgetHandler _parent != null");
        Debugger.Assert(_subBlock != null, "BoxRootWidgetHandler _subBlock != null");
        Debugger.Assert(colorIndex >= 0, "BoxRootWidgetHandler colorIndex >= 0");
        points.Clear();
        usedHint = false;
        rootIndex = _index;
        subBlock = _subBlock;
        parent = _parent;
        isSet = false;
        isPermitClick = true;
        isReverse = _isReverse;
        editMinPoint = _editMinPoint;
        blockType = _blockType;
        colorIndex = _colorIndex;
        int num = 0;
        for (int i = 0; i < subBlock.Length; i++)
        {
            Point item = BlocksCoordinate.coordinate.coordinate.IndexToPuzzle(subBlock[i]);
            bool flag = false;
            flag = ((!_isReverse) ? (((item.x + item.y) % 2 == 0) ? true : false) : (((item.x + item.y) % 2 != 0) ? true : false));
            int tangramIndex = (item.x + editMinPoint[0] + (((item.y + editMinPoint[1]) % 2 != 0) ? 2 : 0)) % 4;
            Vector3 localPosition = BlocksCoordinate.coordinate.coordinate.PuzzleToWorld(item.x, item.y);
            localPosition.z = -2f;
            points.Add(item);
            if (boxWidgets.Count - 1 < num)
            {
                BoxWidgetHandler item2 = Widget.Create<BoxWidgetHandler>();
                boxWidgets.Add(item2);
            }
            boxWidgets[num].transform.parent = parent.transform;
            boxWidgets[num].transform.localPosition = localPosition;
            boxWidgets[num].transform.localScale = Vector3.one * BlocksCoordinate.coordinate.coordinate.size;
            boxWidgets[num].tag = ((blockType != 0) ? "Untagged" : "_box");
            boxWidgets[num].SetData(colorIndex, flag, tangramIndex, blockType);
            boxWidgets[num].transform.parent = base.transform;
            num++;
        }
        ClearBox(num);
        SetOutline(isShow: false);
        SetRotateRoot();
        DoDataExchange();
    }

    public void DoDataExchange()
    {
    }

    private void SetRotateRoot()
    {
        int num = 0;
        int num2 = 0;
        for (int i = 0; i < points.Count; i++)
        {
            int num3 = num;
            Point point = points[i];
            num = num3 + point.x;
            int num4 = num2;
            Point point2 = points[i];
            num2 = num4 + point2.y;
        }
        float num5 = (float)num / (float)points.Count;
        float num6 = (float)num2 / (float)points.Count;
        float num7 = 9999f;
        int index = 0;
        for (int j = 0; j < points.Count; j++)
        {
            Point point3 = points[j];
            float num8 = Mathf.Abs((float)point3.x - num5);
            Point point4 = points[j];
            float num9 = num8 + Mathf.Abs((float)point4.y - num6);
            if (num7 > num9)
            {
                num7 = num9;
                index = j;
            }
        }
        rotateRoot = boxWidgets[index];
    }

    public Vector3 GetRotatePosition()
    {
        Vector3 position = rotateRoot.transform.position;
        if (rotateRoot.isUp)
        {
            position.y += BlocksCoordinate.coordinate.initCoordinate.SizeY / 2f;
        }
        else
        {
            position.y -= BlocksCoordinate.coordinate.initCoordinate.SizeY / 2f;
        }
        return position;
    }

    public void ClearBox(int index = 0)
    {
        for (int i = index; i < boxWidgets.Count; i++)
        {
            UnityEngine.Object.Destroy(boxWidgets[i].gameObject);
        }
        boxWidgets.RemoveRange(index, boxWidgets.Count - index);
    }

    public void SetInitValidPosition(List<BoardInfo> boardInfos, Point currentRootPoint, bool isSet)
    {
        Debugger.Assert(boardInfos != null, "BoxRootWidgetHandler boardInfos != null");
        for (int j = 0; j < points.Count; j++)
        {
            Point gapPoint;
            int itemIndex = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, j);
            if (itemIndex < 0)
            {
                continue;
            }
            boardInfos[itemIndex].index = ((!isSet) ? (-1) : rootIndex);
            boardInfos[itemIndex].colorIndex = colorIndex;
            List<Point> neighborPoints = new List<Point>();
            if (GameMode.gameMode == GameType.TRIANGLE)
            {
                neighborPoints = GetTriangleNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.SQUARE)
            {
                neighborPoints = GetSquareNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.HEXA)
            {
                neighborPoints = GetHexaNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.RHOMBUS)
            {
                neighborPoints = GetRhombusNeighborPoints(gapPoint);
            }
            else if (GameMode.gameMode == GameType.TANGRAM)
            {
                neighborPoints = GetTangramNeighborPoints(gapPoint);
            }
            int i;
            for (i = 0; i < neighborPoints.Count; i++)
            {
                int num = boardInfos.FindIndex((BoardInfo item) => item.point == neighborPoints[i]);
                if (num >= 0)
                {
                    boardInfos[num].index = ((!isSet) ? (-1) : rootIndex);
                }
            }
        }
    }

    private List<Point> GetTriangleNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y));
        list.Add(new Point(point.x + 1, point.y));
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 1, point.y - 1));
        list.Add(new Point(point.x - 1, point.y + 1));
        list.Add(new Point(point.x + 1, point.y - 1));
        list.Add(new Point(point.x + 1, point.y + 1));
        if (((point.x + point.y) % 2 == 0) ? true : false)
        {
            list.Add(new Point(point.x - 2, point.y - 1));
            list.Add(new Point(point.x + 2, point.y - 1));
        }
        else
        {
            list.Add(new Point(point.x - 2, point.y + 1));
            list.Add(new Point(point.x + 2, point.y + 1));
        }
        return list;
    }

    private List<Point> GetSquareNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y));
        list.Add(new Point(point.x + 1, point.y));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 1, point.y - 1));
        list.Add(new Point(point.x - 1, point.y + 1));
        list.Add(new Point(point.x + 1, point.y - 1));
        list.Add(new Point(point.x + 1, point.y + 1));
        return list;
    }

    private List<Point> GetHexaNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x - 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        return list;
    }

    private List<Point> GetRhombusNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list.Add(new Point(point.x - 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x - 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y + ((point.x % 2 != 0) ? 1 : 0)));
        list.Add(new Point(point.x + 1, point.y - ((point.x % 2 == 0) ? 1 : 0)));
        list.Add(new Point(point.x, point.y + 1));
        list.Add(new Point(point.x, point.y - 1));
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        return list;
    }

    private List<Point> GetTangramNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        list = GetSquareNeighborPoints(point);
        list.Add(new Point(point.x - 2, point.y));
        list.Add(new Point(point.x + 2, point.y));
        list.Add(new Point(point.x + 3, point.y));
        list.Add(new Point(point.x - 3, point.y));
        list.Add(new Point(point.x - 2, point.y + 1));
        list.Add(new Point(point.x - 2, point.y - 1));
        list.Add(new Point(point.x + 2, point.y + 1));
        list.Add(new Point(point.x + 2, point.y - 1));
        list.Add(new Point(point.x + 3, point.y - 1));
        list.Add(new Point(point.x + 3, point.y + 1));
        list.Add(new Point(point.x - 3, point.y - 1));
        list.Add(new Point(point.x - 3, point.y + 1));
        return list;
    }

    public void SetValidPosition(List<BoardInfo> boardInfos, Point currentRootPoint)
    {
        Debugger.Assert(boardInfos != null, "BoxRootWidgetHandler boardInfos != null");
        for (int i = 0; i < points.Count; i++)
        {
            Point gapPoint;
            int itemIndex = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, i);
            if (itemIndex >= 0)
            {
                boardInfos[itemIndex].index = rootIndex;
                boardInfos[itemIndex].colorIndex = colorIndex;
                boardInfos[itemIndex].blockTangramIndex = boxWidgets[i].tangramIndex;
            }
        }
    }

    public void RemoveLastPosition(List<BoardInfo> boardInfos)
    {
        boardInfos.ForEach(delegate (BoardInfo item)
        {
            if (item.index == rootIndex)
            {
                item.index = -1;
            }
        });
    }

    public bool IsValidPosition(List<BoardInfo> boardInfos, Point currentRootPoint, bool isDrag = false)
    {
        Debugger.Assert(boardInfos != null, "BoxRootWidgetHandler boardInfos != null");
        for (int i = 0; i < points.Count; i++)
        {
            Point gapPoint;
            int itemIndex = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, i);
            if (itemIndex < 0)
            {
                return false;
            }
            if (boardInfos[itemIndex].index >= 0)
            {
                return false;
            }
            if (i == 0 && boardInfos[itemIndex].isUp != boxWidgets[0].isUp && GameMode.gameMode == GameType.TRIANGLE)
            {
                return false;
            }
            if (isDrag && i == 0 && boardInfos[itemIndex].tangramIndex % 2 != boxWidgets[0].tangramIndex % 2 && GameMode.gameMode == GameType.TANGRAM)
            {
                return false;
            }
            if (!isDrag || GameMode.gameMode != GameType.TANGRAM)
            {
                continue;
            }
            int itemIndex2 = GetItemIndex(out gapPoint, boardInfos, currentRootPoint, i, isTangram: true);
            if (itemIndex2 < 0 && boardInfos[itemIndex].tangramIndex != boxWidgets[i].tangramIndex)
            {
                return false;
            }
            if (itemIndex2 >= 0 && boardInfos[itemIndex2].index >= 0)
            {
                int num = (boxWidgets[i].tangramIndex % 2 != 0) ? (boxWidgets[i].tangramIndex - 1) : (boxWidgets[i].tangramIndex + 1);
                if (num != boardInfos[itemIndex2].blockTangramIndex)
                {
                    return false;
                }
            }
        }
        return true;
    }

    private int GetItemIndex(out Point gapPoint, List<BoardInfo> boardInfos, Point currentRootPoint, int index, bool isTangram = false)
    {
        int x = currentRootPoint.x;
        Point point2 = points[0];
        int num = x - point2.x;
        int y = currentRootPoint.y;
        Point point3 = points[0];
        int num2 = y - point3.y;
        int num3;
        if (GameMode.gameMode == GameType.HEXA)
        {
            num3 = num2;
            Point point4 = points[0];
            if (point4.x % 2 == 0)
            {
                Point point5 = points[index];
                if (point5.x % 2 != 0 && num % 2 != 0)
                {
                    num3++;
                    goto IL_00e2;
                }
            }
            Point point6 = points[0];
            if (point6.x % 2 != 0)
            {
                Point point7 = points[index];
                if (point7.x % 2 == 0 && num % 2 != 0)
                {
                    num3--;
                }
            }
            goto IL_00e2;
        }
        int num4;
        if (GameMode.gameMode == GameType.RHOMBUS)
        {
            num4 = num2;
            Point point8 = points[0];
            if (point8.x % 2 == 0)
            {
                Point point9 = points[index];
                if (point9.x % 2 != 0 && num % 2 != 0)
                {
                    num4++;
                    goto IL_01bf;
                }
            }
            Point point10 = points[0];
            if (point10.x % 2 != 0)
            {
                Point point11 = points[index];
                if (point11.x % 2 == 0 && num % 2 != 0)
                {
                    num4--;
                }
            }
            goto IL_01bf;
        }
        Point point12 = points[index];
        int x2 = point12.x + num;
        Point point13 = points[index];
        gapPoint = new Point(x2, point13.y + num2);
        goto IL_0231;
        IL_00e2:
        Point point14 = points[index];
        int x3 = point14.x + num;
        Point point15 = points[index];
        gapPoint = new Point(x3, point15.y + num3);
        goto IL_0231;
        IL_0231:
        Point point = new Point(gapPoint.x, gapPoint.y);
        if (isTangram)
        {
            int num5 = boardInfos.FindIndex((BoardInfo item) => item.point == point);
            if (num5 >= 0)
            {
                point.x = ((boardInfos[num5].tangramIndex % 2 != 0) ? (point.x - 1) : (point.x + 1));
            }
        }
        return boardInfos.FindIndex((BoardInfo item) => item.point == point);
        IL_01bf:
        Point point16 = points[index];
        int x4 = point16.x + num;
        Point point17 = points[index];
        gapPoint = new Point(x4, point17.y + num4);
        goto IL_0231;
    }

    public void SetOutline(bool isShow)
    {
        for (int i = 0; i < boxWidgets.Count; i++)
        {
            boxWidgets[i].SetOutline(isShow);
        }
    }

    public void SetPoints(GameObject initPoint, bool isRotate = false)
    {
        for (int i = 0; i < boxWidgets.Count; i++)
        {
            boxWidgets[i].transform.parent = base.transform;
        }
    }

    public void SetOverlapColor(BoxRootWidgetHandler targetWidget)
    {
        Debugger.Assert(targetWidget != null, "BoxRootWidgetHandler targetWidget != null");
        for (int i = 0; i < points.Count; i++)
        {
            for (int j = 0; j < targetWidget.points.Count; j++)
            {
                if (targetWidget.points[j] == points[i])
                {
                    boxWidgets[i].sprite.color = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, 100);
                    break;
                }
            }
        }
    }
}
